package server;

import org.dom4j.Attribute;
import org.dom4j.Element;

import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author: wudong
 * @create: 2021-07-27 13:40
 **/
public class Service extends BaseContainer implements Lifecycle {
    private List<Endpoint> endpoints = new ArrayList<>();
    private Engine engine;
    private ThreadPoolExecutor threadPoolExecutor;

    @Override
    public void init() throws Exception {
        Element element = getElement();

        Attribute name = element.attribute("name");
        if(name != null){
            this.setName(name.getValue());
        }
        //处理Engine
        Element ele = (Element)element.selectSingleNode("Engine");
        Engine engine = new Engine();
        engine.setElement(ele);
        engine.init();
        this.engine = engine;

        //处理connenct
        List connectors = element.selectNodes("Connector");
        for (Object obj : connectors) {
            Element connect = (Element)obj;
            String port = connect.attribute("port").getValue();
            Endpoint endpoint = new Endpoint(Integer.parseInt(port), new Handler() {
                @Override
                public void process(Socket socket) {
                    RequestProcessor requestProcessor = new RequestProcessor(socket,engine);
                    threadPoolExecutor.execute(requestProcessor);
                }
            });

            endpoint.init();
            endpoints.add(endpoint);
        }

        // 定义一个线程池
        int corePoolSize = 10;
        int maximumPoolSize =50;
        long keepAliveTime = 100L;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();

        this.threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );
    }

    @Override
    public void start() throws Exception {
        engine.start();

        for (Endpoint endpoint : endpoints) {
            endpoint.start();
        }
    }

}
